# frozen_string_literal: true

require 'spec_helper'

RSpec.describe VulnerabilityExports::ExportWorker, type: :worker, feature_category: :vulnerability_management do
  let(:worker) { described_class.new }

  describe '#perform' do
    subject(:export_vulnerabilities) { worker.perform(vulnerability_export_id) }

    before do
      allow(VulnerabilityExports::ExportService).to receive(:export)
      allow(Sidekiq.logger).to receive(:error)
    end

    context 'when vulnerability export does not exist' do
      let(:vulnerability_export_id) { nil }

      it 'does not raise any error' do
        expect { export_vulnerabilities }.not_to raise_error
      end

      it 'does not call VulnerabilityExports::ExportService::export' do
        export_vulnerabilities

        expect(VulnerabilityExports::ExportService).not_to have_received(:export)
      end
    end

    context 'when vulnerability export exists' do
      let(:vulnerability_export) { create(:vulnerability_export, :created, :csv) }
      let(:vulnerability_export_id) { vulnerability_export.id }

      it 'calls VulnerabilityExports::ExportService::export with the vulnerability_export object' do
        export_vulnerabilities

        expect(VulnerabilityExports::ExportService).to have_received(:export).with(vulnerability_export)
      end
    end
  end

  describe 'sidekiq_retries_exhausted callback' do
    let(:sidekiq_retry_handler) { Sidekiq::JobRetry.new(Sidekiq) }
    let(:vulnerability_export) { create(:vulnerability_export, :created, :csv) }
    let(:default_job_payload) { { 'class' => described_class.name, 'args' => [vulnerability_export.id] } }

    subject(:run_job) do
      sidekiq_retry_handler.local(worker, job_payload.to_json, 'default') do
        raise 'Foo'
      end
    end

    context 'when the max retry count is not reached' do
      let(:job_payload) { default_job_payload.merge('retry_count' => 1) }

      it 'does not mark the vulnerability export object as failed' do
        expect { run_job }.to raise_error(Sidekiq::JobRetry::Skip)
                          .and not_change { vulnerability_export.reload.failed? }.from(false)
      end
    end

    context 'when the max retry count is reached' do
      let(:job_payload) { default_job_payload.merge('retry_count' => 2) }

      it 'marks the vulnerability export object as failed' do
        expect { run_job }.to raise_error(Sidekiq::JobRetry::Skip)
                          .and change { vulnerability_export.reload.failed? }.from(false).to(true)
      end
    end
  end
end
